/*
 * Funny Language - a free style programming language.
 * Copyright (C) 2015 by fanguangping (fanguangping@163.com)
 * test_queue.c
 */

#include <string.h>
#include "runner_ds.h"

static void test_alloc_queue() {
	Queue *queue = alloc_queue();
	assert_non_null(queue);
}

static void test_alloc_queue_node() {
	QueueNode *node = alloc_queue_node();
	assert_non_null(node);
}

static void test_init_queue() {
	Queue *queue = init_queue();
	assert_non_null(queue);
	assert_null(queue->head);
	assert_null(queue->tail);
}

static void test_enqueue() {
	Queue *queue = init_queue();
	enqueue(queue, "abc");
	assert_ptr_equal(queue->head, queue->tail);
	assert_string_equal(queue->head->element, "abc");
	enqueue(queue, "def");
	assert_string_equal(queue->head->next->element, "def");
	assert_string_equal(queue->tail->element, "def");
}

static void test_dequeue() {
	Queue *queue = init_queue();
	enqueue(queue, "abc");
	enqueue(queue, "def");
	char *str = dequeue(queue);
	assert_string_equal(str, "abc");
	assert_ptr_equal(queue->head, queue->tail);
	str = dequeue(queue);
	assert_string_equal(str, "def");
	assert_null(queue->head);
	assert_null(queue->tail);
	assert_null(dequeue(queue));
}

static void test_get_queue_element() {
	Queue *queue = init_queue();
	enqueue(queue, "abc");
	enqueue(queue, "def");
	assert_string_equal(get_queue_element(queue, 0), "abc");
	assert_string_equal(get_queue_element(queue, 1), "def");
	assert_null(get_queue_element(queue, 2));
	assert_null(get_queue_element(queue, -1));
}

static void test_is_queue_empty() {
	assert_true(is_queue_empty(NULL));
	Queue *queue = init_queue();
	assert_true(is_queue_empty(queue));
	enqueue(queue, "abc");
	dequeue(queue);
	assert_true(is_queue_empty(queue));
}

static void test_clear_queue() {
	clear_queue(NULL);
	Queue *queue = init_queue();
	clear_queue(queue);
	assert_true(is_queue_empty(queue));
	enqueue(queue, "abc");
	enqueue(queue, "def");
	clear_queue(queue);
	assert_true(is_queue_empty(queue));
}

static void test_append_queue() {
	Queue *q1 = init_queue();
	enqueue(q1, "abc");
	Queue *q2 = init_queue();
	enqueue(q2, "def");
	append_queue(q1, q2);
	append_queue(q1, NULL);
	append_queue(NULL, NULL);
	assert_string_equal(q1->head->next->element, "def");
}

static void test_contains_queue_element() {
	Queue *queue = init_queue();
	enqueue(queue, "abc");
	enqueue(queue, "def");
	assert_true(contains_queue_element(queue, "abc", equals_string));
	assert_true(contains_queue_element(queue, "def", equals_string));
	assert_false(contains_queue_element(queue, "ghi", equals_string));
	assert_false(contains_queue_element(queue, NULL, equals_string));
	assert_false(contains_queue_element(NULL, NULL, equals_string));
}

static void test_get_queue_element_index() {
	Queue *queue = init_queue();
	enqueue(queue, "abc");
	enqueue(queue, "def");
	assert_int_equal(get_queue_element_index(queue, "abc", equals_string), 0);
	assert_int_equal(get_queue_element_index(queue, "def", equals_string), 1);
	assert_int_equal(get_queue_element_index(queue, "ghi", equals_string), -1);
	assert_int_equal(get_queue_element_index(queue, NULL, equals_string), -1);
	assert_int_equal(get_queue_element_index(NULL, NULL, equals_string), -1);
}

static void test_count_queue_element() {
	assert_int_equal(count_queue_element(NULL), -1);
	Queue *queue = init_queue();
	assert_int_equal(count_queue_element(queue), 0);
	enqueue(queue, "abc");
	assert_int_equal(count_queue_element(queue), 1);
	enqueue(queue, "def");
	assert_int_equal(count_queue_element(queue), 2);
}

int main(int argc, char **argv) {
	const struct CMUnitTest tests[] = {
			cmocka_unit_test(test_alloc_queue),
			cmocka_unit_test(test_alloc_queue_node),
			cmocka_unit_test(test_init_queue),
			cmocka_unit_test(test_enqueue),
			cmocka_unit_test(test_dequeue),
			cmocka_unit_test(test_get_queue_element),
			cmocka_unit_test(test_is_queue_empty),
			cmocka_unit_test(test_clear_queue),
			cmocka_unit_test(test_append_queue),
			cmocka_unit_test(test_contains_queue_element),
			cmocka_unit_test(test_get_queue_element_index),
			cmocka_unit_test(test_count_queue_element),
	};
	return cmocka_run_group_tests(tests, NULL, NULL);
}
